package com.mgang.mgds4j.core;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * 
 * @author meigang 2014-11-28 18:44
 * 数据源工厂(工厂模式，反射)
 */
public abstract class MgDataSourceFactory {
	private static String name;
	private static String clazz;
	private static String destory;
	private static Map<String,Object> contants = new HashMap<String, Object>();
	private static MgDataSource ds;
	
	private static Map<String,MgDataSource> factory = new HashMap<String, MgDataSource>();
	/**
	 * 构建工厂
	 */
	public static void build(){
		try {
			initMgds4jFormXml();
			//初始化连接池
			ds.initConnectionPool();
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 解析mgds4j.xml配置文件，默认的路径在classpath根目录下
	 * @throws DocumentException 
	 */
	private static void initMgds4jFormXml() throws DocumentException{
		SAXReader reader = new SAXReader();
		
		Document doc = reader.read(MgDataSourceFactory.class.getClassLoader().getResourceAsStream("mgds4j.xml"));
		Element rootElement = doc.getRootElement(); // 获取根节点
		//加载mgds4j.xml中的contant常量到map集合中
		Iterator constantElements = rootElement.elementIterator("constant");
		while(constantElements.hasNext()){
			Element constantElement = (Element) constantElements.next();
			contants.put(constantElement.attributeValue("key"), constantElement.attributeValue("value"));
		}
		//加载mgds4j.xml中的数据源
		Iterator dsElements = rootElement.elementIterator("dataSource"); // 获取根节点下的子节点dataSource
		while(dsElements.hasNext()){
			//只有一个dataSource,【如果不止一个数据源配置】
			Element dsElement = (Element) dsElements.next();
			name = dsElement.attributeValue("name");
			clazz = dsElement.attributeValue("class");
			destory = dsElement.attributeValue("destory");
			try {
				//通过调用static函数getInstance来得到单例对象
				Class dsClass = Class.forName(clazz);
				ds = (MgDataSource) dsClass.getMethod("getInstance", null).invoke(dsClass, null);
				factory.put(name, ds);
			
				//得到dataSource下的property节点
				Iterator ps = dsElement.elementIterator("property"); 
				while(ps.hasNext()){
					Element propertyElement = (Element) ps.next();
					String key = propertyElement.attributeValue("key");
					String value = propertyElement.attributeValue("value");
					String type = propertyElement.attributeValue("type");
					if(type.equals("string")){
						Method m = MgDataSource.class.getMethod("set"+UpperFirst(key),String.class);
						m.invoke(ds, value);
					}else if(type.equals("int")){
						Method m = MgDataSource.class.getMethod("set"+UpperFirst(key),int.class);
						m.invoke(ds, Integer.parseInt(value.trim()));
					}
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	/**
	 * 得到MgDataSource数据源从工厂中
	 * @param name 数据源在mgds4j.xml中配置的name
	 * @return 返回MgDataSource数据源对象
	 */
	public static MgDataSource getMgDataSource(String name){
		return factory.get(name);
	}
	/**
	 * 首字母大写
	 * @param str
	 * @return
	 */
	private static String UpperFirst(String str){
		return (str.charAt(0)+"").toString().toUpperCase()+str.substring(1, str.length());
	}
	/**
	 * 从contants常量map中得到对应key的常量值
	 * @param key
	 * @return
	 */
	public static Object getContant(String key){
		return contants.get(key);
	}
}
